package nl.ypmits.utils.as3.date.clock {
	import nl.ypmits.utils.as3.date.clock.type.ClockType;

	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.utils.Timer;

	/**
	 * @author Dave Lenz
	 */
	public class Clock extends Sprite {

		[Embed(source="../../../../../../assets/pf_ronda_seven.ttf", fontName="PF Ronda Seven", mimeType="application/x-font")]

		private var Ronda : Class;
		private var timer : Timer;
		private var skin : ClockSkin;
		private var type : String;
		private var tf : TextField;
		private var obj : ClockObject = new ClockObject( );
		
		private var precedingZero : Boolean;
		private var preciseBigHandles : Boolean;
		private var bouncySeconds : Boolean;

		
		public function Clock( _clocktype : String, _skin : ClockSkin = null, precedingZero : Boolean = true, preciseBigHandles : Boolean = true, bouncySeconds : Boolean = true ) {
			
			type = _clocktype;
			if( _skin ) skin = _skin;
			this.precedingZero = precedingZero;
			this.preciseBigHandles = preciseBigHandles;
			this.bouncySeconds = bouncySeconds;
			
			if( type == ClockType.DIGITAL ) {
				checkForDigitalSkin( );
			} else if ( type == ClockType.ANALOGUE ) {
				checkForAnalogueSkin( );
			} else {
				throw new Error( "ERROR! You must set a ClockType to either ClockType.DIGITAL or ClockType.ANALOGUE" );
			}
		}

		
		private function checkForDigitalSkin() : void {
			tf = new TextField( );
			tf.embedFonts = true;
			tf.selectable = false;
			tf.type = TextFieldType.INPUT;
			if( skin.validateDigital( ) ) {
				tf.defaultTextFormat = new TextFormat( skin.fontName, 8, 0x000000 );
				addChild( tf );
			} else {
				tf.defaultTextFormat = new TextFormat( "PF Ronda Seven", 8, 0x000000 );
				addChild( tf );
			}
		}

		
		private function checkForAnalogueSkin() : void {
			var uur : Sprite;
			var minuten : Sprite;
			var seconden : Sprite;
			
			if( skin ) {
				if( skin.validateAnalogue( ) ) {
					uur = Sprite( skin.hourGraphic );
					minuten = Sprite( skin.minutesGraphic );
					seconden = Sprite( skin.secondsGraphic );
				}
			} else {
				uur = new Sprite( );
				uur.graphics.lineStyle( 3, 0x666666, 1 );
				uur.graphics.moveTo( 0, 0 );
				uur.graphics.lineTo( 70, 0 );
				
				minuten = new Sprite( );
				minuten.graphics.lineStyle( 2, 0x666666, 1 );
				minuten.graphics.moveTo( 0, 0 );
				minuten.graphics.lineTo( 100, 0 );
				
				seconden = new Sprite( );
				seconden.graphics.lineStyle( 1, 0x666666, 1 );
				seconden.graphics.moveTo( 0, 0 );
				seconden.graphics.lineTo( 110, 0 );
			}
			addChild( uur );
			addChild( minuten );
			addChild( seconden );
		}

		
		public function start() : void {
			timer = new Timer( 1000 );
			timer.addEventListener( TimerEvent.TIMER, timerListener );
			timer.start( );
			timerListener( );
		}

		
		public function stop() : void {
			timer.stop( );
			timer.removeEventListener( TimerEvent.TIMER, timerListener );
			timer.reset( );
			timer = null;
		}

		
		public function getClockObject() : ClockObject {
			var date : Date = new Date( );
			obj.year = date.fullYear;
			obj.month = date.month;
			obj.day = date.day;
			obj.hours = date.hours;
			obj.minutes = date.minutes;
			obj.seconds = date.seconds;
			obj.milliseconds = date.milliseconds;
			return obj;
		}

		
		private function timerListener( e : TimerEvent = null ) : void {
			var date : Date = new Date( );
			if( type == ClockType.ANALOGUE ) {
				var hNum : Number;
				date.hours > 12 ? hNum = date.hours - 12 : hNum = date.hours;
				skin.hourGraphic.rotation = ((360 / 12) * hNum) + (((360 / 12) / 60) * date.minutes - 90);
				skin.minutesGraphic.rotation = ((360 / 60) * date.minutes - 90) + (((360 / 60) / 60) * date.seconds);
				skin.secondsGraphic.rotation = (360 / 60) * date.seconds - 90;
			} else if ( type == ClockType.DIGITAL ) {
				var hString : String;
				var mString : String;
				var sString : String;
				if( precedingZero ) {
					String( date.hours ).length == 1 ? hString = "0" + String( date.hours ) : hString = String( date.hours );
					String( date.minutes ).length == 1 ? mString = "0" + String( date.minutes ) : mString = String( date.minutes );
					String( date.seconds ).length == 1 ? sString = "0" + String( date.seconds ) : sString = String( date.seconds );
				}
				tf.text = hString + ":" + mString + ":" + sString;
			}
		}

		
		public function dispose() : void {
			skin.dispose( );
			skin = null;
			type = "";
			if( tf ) removeChild( tf );
			tf = null;

			timer.stop( );
			timer.removeEventListener( TimerEvent.TIMER, timerListener );
			timer.reset( );
			timer = null;
		}
	}
}
